package com.utc.teamcenter.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

public class DateUtils {

	public static String getDateValue(Object o) {
		String result = getSystemDate("yyyy-MM-dd");
		if (o != null) {
			result = o.toString();
		}
		return result;
	}

	public static Date transStringToDate(String datestr, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date date = new Date();
		try {
			date = sdf.parse(datestr);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return date;
	}

	public static String getKWByDate(String date) {
		int kw = (Integer) (((Map) DateUtils.getYearWeekString(date))
				.get("weeks"));
		String year = (date.split("-")[0]).substring(2, 4);
		return "KW" + kw + "/" + year;
	}

	public static String getLastTwoNum(int year) {
		return (String) (year + "").subSequence(2, 4);
	}

	public static int getMaxWeekNumOfYear(int year) {
		Calendar c = new GregorianCalendar();
		c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
		Map map = getYearWeekDate(c.getTime());
		int weeks = (Integer) map.get("weeks");
		return weeks;
	}

	public static Date getDate(int year, int month, int date) {
		Calendar c = Calendar.getInstance();
		c.set(year, month, date);
		return new Date(year, month, date);
	}

	public static String getCurrentYear() {
		return getSystemDate("yyyy-MM-dd").split("-")[0];
	}

	public static Boolean betweenStartAndEnd(String selectTime,
			String startTime, String endTime) {

		if (compareTime(startTime, selectTime)
				&& compareTime(selectTime, endTime)) {
			return true;
		}

		return false;
	}

	public static int compareDaysBetweenTwoDate(String date1, String date2) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		long d1 = 0;
		long d2 = 0;
		try {
			d1 = sdf.parse(date1).getTime();
			d2 = sdf.parse(date2).getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return (int) Math.abs((d1 - d2) / 1000 / 60 / 60 / 24);
	}

	public static String transformTime(String oldTime, String pattern) {
		String newTime = oldTime;
		if ("MM.dd".equals(pattern) && !"".equals(oldTime)) {
			newTime = oldTime.split(" ")[0].split("-")[1] + "."
					+ oldTime.split(" ")[0].split("-")[2];
		}
		if ("YYYY.MM.dd".equals(pattern) && !"".equals(oldTime)) {
			newTime = oldTime.split(" ")[0].split("-")[0] + "."
					+ oldTime.split(" ")[0].split("-")[1] + "."
					+ oldTime.split(" ")[0].split("-")[2];
		}
		if ("YY".equals(pattern) && !"".equals(oldTime)) {
			newTime = oldTime.split(" ")[0].split("-")[0].substring(2, 4);
		}
		return newTime;

	}

	public static boolean compareTime(String date1, String date2) {
		Date startDate = new Date();
		Date endDate = new Date();
		try {
			if (!"".equals(date1)) {
				startDate = new SimpleDateFormat("yyyy-MM-dd HH:mm")
						.parse(date1);
			}
			if (!"".equals(date2)) {
				endDate = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(date2);
			}
			if ((startDate.getTime() - endDate.getTime()) / 3600 / 24 / 1000 <= 0) {
				return true;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;

	}

	public static Date getFirstDayOfWeek(int year, int week) {
		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, 1);

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, week * 7);

		return getFirstDayOfWeek(cal.getTime());
	}

	public static Date getLastDayOfWeek(int year, int week) {
		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, 1);

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, week * 7);

		return getLastDayOfWeek(cal.getTime());
	}

	/**
     */
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.SUNDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
		return c.getTime();
	}

	/**
     */
	public static Date getLastDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
		return c.getTime();
	}

	/**
     */
	public static Date getFirstDayOfWeek() {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(new Date());
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
		return c.getTime();
	}

	/**
     */
	public static Date getLastDayOfWeek() {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(new Date());
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
		return c.getTime();
	}

	/**
	 * 
	 * @param dateStr
	 *            "yyyy-MM-dd hh:mm"
	 * @param n
	 * @return date_str
	 */
	public static String oneDateAddOrSubDays(String dateStr, int n, String flag) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date tmpDate = null;
		try {
			tmpDate = df.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long n_day = 0L;
		if ("+".equals(flag)) {
			n_day = (tmpDate.getTime() / (24 * 60 * 60 * 1000) + 1 + n)
					* (24 * 60 * 60 * 1000);
		}
		if ("-".equals(flag)) {
			n_day = (tmpDate.getTime() / (24 * 60 * 60 * 1000) + 1 - n)
					* (24 * 60 * 60 * 1000);
		}

		tmpDate.setTime(n_day);

		return df.format(tmpDate);
	}

	/**
     */
	public static String getDateAddMonth(String dateStr, int month, String flag) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = new Date();
		try {
			date = sdf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calender = Calendar.getInstance();
		calender.setTime(date);
		if ("+".equals(flag)) {
			calender.add(Calendar.MONTH, month);
		}
		if ("-".equals(flag)) {
			calender.add(Calendar.MONTH, -month);
		}

		sdf.format(calender.getTime());
		return sdf.format(calender.getTime()).toString();

	}

	/**
     */
	public static int dateDiff(Date startDate, Date endDate) {

		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		long ns = 1000;

		long diff = 0l;
		long day = 0l;
		if (startDate != null && endDate != null) {
			diff = endDate.getTime() - startDate.getTime();
		}

		day = diff / nd;
		long hour = diff % nd / nh;
		long min = diff % nd % nh / nm;
		long sec = diff % nd % nh % nm / ns;

		return new Long(day).intValue();
	}

	/**
     */
	public static int getTwoDateSepMonths(String datestr1, String datestr2) {
		Date date1 = new Date();
		Date date2 = new Date();
		int iMonth = 0;
		int flag = 0;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			date1 = sdf.parse(datestr1);
			date2 = sdf.parse(datestr2);

			Calendar objCalendarDate1 = Calendar.getInstance();
			objCalendarDate1.setTime(date1);
			Calendar objCalendarDate2 = Calendar.getInstance();
			objCalendarDate2.setTime(date2);
			if (objCalendarDate2.equals(objCalendarDate1))
				return 0;
			if (objCalendarDate1.after(objCalendarDate2)) {
				Calendar temp = objCalendarDate1;
				objCalendarDate1 = objCalendarDate2;
				objCalendarDate2 = temp;
			}
			if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1
					.get(Calendar.DAY_OF_MONTH))
				flag = 1;
			if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1
					.get(Calendar.YEAR))
				iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1
						.get(Calendar.YEAR))
						* 12 + objCalendarDate2.get(Calendar.MONTH) - flag)
						- objCalendarDate1.get(Calendar.MONTH);
			else
				iMonth = objCalendarDate2.get(Calendar.MONTH)
						- objCalendarDate1.get(Calendar.MONTH) - flag;
		} catch (ParseException e1) {
			e1.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return iMonth;
	}

	/*
     */
	public static int getTwoTenDays(String datestr) {
		int day = Integer.parseInt(datestr.split("-")[2]);
		if (day >= 1 && day <= 15)
			return 1;
		if (day >= 16 && day <= 31)
			return 2;

		return 1;
	}

	/*
     */
	public static int getThreeTenDays(String datestr) {
		int day = Integer.parseInt(datestr.split("-")[2]);
		if (day >= 1 && day <= 10)
			return 1;
		if (day >= 11 && day <= 20)
			return 2;
		if (day >= 21 && day <= 31)
			return 3;

		return 1;
	}

	/**
	 * @param formatStr
	 * @return
	 */
	public static String getSystemTime(String formatStr) {
		if (formatStr == null || "".equals(formatStr)) {
			formatStr = "yyyy-MM-dd HH:mm:ss";
		}

		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.format(date);
	}

	/**
	 * @param formatStr
	 * @return
	 */
	public static String getSystemDate(String formatStr) {
		if (formatStr == null || "".equals(formatStr)) {
			formatStr = "yyyy-MM-dd";
		}

		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.format(date);
	}

	public static Map<String, Object> getYearWeekString(String date) {
		if (date.contains(" ")) {
			date = date.split(" ")[0];
		}
		int year = Integer.parseInt(date.split(("-"))[0]);
		int month = Integer.parseInt(date.split(("-"))[1]);
		int day = Integer.parseInt(date.split(("-"))[2]);
		// System.out.println("year="+year+"month"+month+"day"+day);
		Map<String, Object> yearWeek = getYearWeek(year, month, day);
		return yearWeek;
	}

	public static Map<String, Object> getYearWeekDate(Date date) {
		Calendar cc = Calendar.getInstance();
		cc.setTime(date);
		System.out.println(date);
		int year = cc.get(cc.YEAR);
		int month = cc.get(cc.MONTH) + 1;
		int day = cc.get(cc.DATE);
		// System.out.println("year="+year+"month"+month+"day"+day);
		Map<String, Object> yearWeek = getYearWeek(year, month, day);
		return yearWeek;
	}

	public static Map<String, Object> getYearWeek(int year, int month, int day) {

		Map<String, Object> yearWeek = new HashMap<String, Object>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		int thisYear = year;
		String ydatetime = ydatetime = year + "-" + month + "-" + day;
		Date ydate = null;
		String firstDateTime = year + "-1-1";
		Date firstDate = null;

		int yweek;
		try {
			firstDate = sdf.parse(firstDateTime);
			ydate = sdf.parse(ydatetime);
			int firstDay = firstDate.getDay();
			double thisDays = (ydate.getTime() - firstDate.getTime()) / 86400000 + 1;
			// System.out.println("thisDays=" + thisDays + "ydate=" + ydate
			// + "firstdate=" + firstDate + "firstDay=" + firstDay);
			if (firstDay > 4) {
				thisDays = thisDays - (7 - firstDay);
			} else {
				thisDays = thisDays + firstDay;
			}
			if (thisDays > 0) {
				yweek = (int) Math.ceil(thisDays / 7);
			} else {
				year--;
				thisYear = year;
				yweek = getISOWeekAll(year);
			}
			yearWeek.put("weeks", yweek);
			yearWeek.put("year", thisYear);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return yearWeek;
	}

	public static int getISOWeekAll(int year) {
		int yweekcount = 0;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date firstdate = null;
		String firstDateTime = year + "-1-1";
		Date lastdate = null;
		String lastDateTime = year + "-12-31";
		try {
			firstdate = sdf.parse(firstDateTime);
			lastdate = sdf.parse(lastDateTime);
			double countday = (lastdate.getTime() - firstdate.getTime()) / 86400000 + 1;
			int firstDay = firstdate.getDay();
			if (firstDay == 0)
				firstDay = +7;
			if (firstDay > 4) {
				countday = countday - (8 - firstDay);
			} else {
				countday = (countday - 1) + firstDay;
			}
			int lastDay = lastdate.getDay();
			if (lastDay == 0)
				lastDay = +7;
			if (lastDay > 3) {
				countday = countday + (7 - lastDay);
			} else {
				countday = countday - lastDay;
			}
			yweekcount = (int) (countday / 7);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return yweekcount;
	}

}
